package org.mspring.platform.weibo.tencent;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.apache.commons.io.FileUtils;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.mspring.platform.utils.PropertyConfigurer;
import org.mspring.platform.utils.StringUtils;
import org.mspring.platform.utils.http.HttpUtils;
import org.mspring.platform.weibo.em.Format;
import org.mspring.platform.weibo.exception.OAuthException;
import org.mspring.platform.weibo.tencent.entity.TencentUserinfo;
import org.mspring.platform.weibo.tencent.entity.dto.APIResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;

/**
 *
 * @author Gao Youbo
 * @since 2014年5月19日
 */
@Service
public class TencentWeiboService {

    private static final Logger log = LoggerFactory.getLogger(TencentWeiboService.class);

    /**
     * OAuth版本
     */
    public static final String OAUTH_VERSION = "2.a";
    /**
     * 授权范围
     */
    public static final String SCOPE = "all";
    /**
     * 返回数据格式，固定为JSON
     */
    public static final Format format = Format.JSON;

    /**
     * 发表微博
     */
    public static final String ADD_URL = "https://open.t.qq.com/api/t/add";
    /**
     * 发表图片微博
     */
    public static final String ADD_PIC_URL = "https://open.t.qq.com/api/t/add_pic";

    private PropertyConfigurer propertyConfigurer;
    private String appkey;
    private String appsecret;

    /**
     * 发布一条微博
     *
     * @param userinfo
     * @param content
     *            微博内容
     * @param clientip
     *            用户IP
     * @return
     * @throws org.mspring.platform.weibo.exception.OAuthException
     */
    public APIResult add(TencentUserinfo userinfo, String content, String clientip) throws OAuthException {
        List<NameValuePair> nvps = getOAuth2BasicParam(userinfo, clientip);
        nvps.add(new BasicNameValuePair("content", content));
        return postApi(ADD_URL, nvps);
    }

    public APIResult addPic(TencentUserinfo userinfo, String content, byte[] pic, String clientip) throws OAuthException {
        List<NameValuePair> nvps = getOAuth2BasicParam(userinfo, clientip);
        nvps.add(new BasicNameValuePair("content", content));
        return postApiWithPic(ADD_PIC_URL, nvps, pic);
    }

    /**
     * OAuth2.0授权协议的通用参数,调用API时需要附带的信息
     *
     * @param userinfo
     * @param clientIp
     * @return
     */
    private List<NameValuePair> getOAuth2BasicParam(TencentUserinfo userinfo, String clientIp) throws OAuthException {
        if (StringUtils.isBlank(userinfo.getAccessToken())) {
            throw new OAuthException("accessToken不能为空");
        }
        if (StringUtils.isBlank(userinfo.getOpenid())) {
            throw new OAuthException("openid不能为空");
        }
        List<NameValuePair> nvps = new ArrayList<>();
        nvps.add(new BasicNameValuePair("format", format.getValue()));
        nvps.add(new BasicNameValuePair("oauth_consumer_key", this.appkey));
        nvps.add(new BasicNameValuePair("access_token", userinfo.getAccessToken()));
        nvps.add(new BasicNameValuePair("openid", userinfo.getOpenid()));
        nvps.add(new BasicNameValuePair("oauth_version", OAUTH_VERSION));
        nvps.add(new BasicNameValuePair("scope", SCOPE));
        nvps.add(new BasicNameValuePair("clientip", clientIp));
        return nvps;
    }

    /**
     * POST请求api接口
     *
     * @param url
     *            接口地址
     * @param nvps
     *            参数列表
     * @return
     */
    private APIResult postApi(String url, List<NameValuePair> nvps) {
        try {
            HttpResponse httpResponse = HttpUtils.post(url, nvps);
            String result = EntityUtils.toString(httpResponse.getEntity());
            return JSON.parseObject(result, APIResult.class);
        } catch (Exception e) {
            log.error("请求接口失败, url=" + url, e);
            return null;
        }
    }

    /**
     * POST请求api接口
     *
     * @param url
     *            接口地址
     * @param nvps
     *            参数列表
     * @param pic
     *            图片
     * @return
     */
    private APIResult postApiWithPic(String url, List<NameValuePair> nvps, byte[] pic) {
        try {
            File temp = null;
            try {
                Map<String, File> files = new HashMap<>();
                if (pic != null && pic.length > 0) {
                    temp = File.createTempFile(UUID.randomUUID().toString(), null);
                    FileUtils.writeByteArrayToFile(temp, pic);
                    files.put("pic", temp);
                }
                HttpResponse httpResponse = HttpUtils.post(url, nvps, files);
                String result = EntityUtils.toString(httpResponse.getEntity());
                return JSON.parseObject(result, APIResult.class);
            } finally {
                if (temp != null) {
                    temp.delete();
                }
            }
        } catch (Exception e) {
            log.error("请求接口失败, url=" + url, e);
            return null;
        }
    }

    @Autowired
    public void setPropertyConfigurer(PropertyConfigurer propertyConfigurer) {
        this.propertyConfigurer = propertyConfigurer;
        this.appkey = this.propertyConfigurer.getString("tencent.appkey");
        this.appsecret = this.propertyConfigurer.getString("tencent.appsecret");
        if (StringUtils.isBlank(this.appkey)) {
            throw new IllegalArgumentException("appkey不能为空");
        }
        if (StringUtils.isBlank(this.appsecret)) {
            throw new IllegalArgumentException("appsecret不能为空");
        }
    }

    public void setAppkey(String appkey) {
        this.appkey = appkey;
    }

}
